package com.by.orders.service.impl;

import com.by.api.dto.CarDto;
import com.by.common.core.bean.ResultBean;
import com.by.common.core.exception.BusinessException;
import com.by.common.core.utils.Assert;
import com.by.feign.client.CarRemoteClient;
import com.by.feign.client.SkuRemoteClient;

import com.by.feign.dto.SkuDto;
import com.by.orders.code.CodeFactory;
import com.by.orders.entity.dto.OrderDto;
import com.by.orders.mapper.OrderAddrMapper;
import com.by.orders.mapper.OrderItemMapper;
import com.by.orders.mapper.OrderMapper;
import com.by.orders.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    CarRemoteClient carRemoteClient;

    @Autowired
    SkuRemoteClient skuRemoteClient;


    @Autowired
    OrderAddrMapper orderAddrMapper;

    @Override
    public int save(OrderDto orderDto) {

        //保存订单
        int rs=orderMapper.saveOrder(orderDto);
        Assert.isZero(rs,"保存订单失败");
        //生成订单编号（暂时写死）
        orderDto.setOrderCode("DD202510001");
        //保存订单项
        rs=orderItemMapper.saveOrderItem(orderDto.getOrderId(),orderDto.getOrderItemList());
        Assert.isZero(rs,"保存订单项失败");
        //保存订单地址
        //如果已有地址只需根据id查询并获取地址即可，如果没有则需添加新的地址
        return 1;

    }

    @Override
    public String saveMobileOrder(int userId) {
        //1.获取 购物车信息
        //获取失败的情况
        ResultBean rs=carRemoteClient.querySelectGoodsFromCar(userId);
        Assert.isZero(rs.getCode(),"获取用户["+userId+"]的购物车信息失败");
        //获取成功
        List<CarDto> list=(List<CarDto>)rs.getData();
        //购物明细
        List<SkuDto> skuDtoList=new ArrayList<>();
        //2.检验库存
        Iterator<CarDto> it=list.iterator();
        while (it.hasNext()){
            //获取当前sku
            CarDto dto=it.next();
            //根据skuid查询对应的库存信息
            rs=skuRemoteClient.querySku(dto.getSkuId());
            //获取失败的情况
            Assert.isZero(rs.getCode(),"查询sku["+dto.getSkuId()+"]信息失败");
            //获取成功
            SkuDto skuDto=(SkuDto) rs.getData();
            //如果查到的商品库存小于购物车要购买商品的数量就上抛异常
            if(skuDto.getStock()<dto.getCount()){
                throw new BusinessException(skuDto.getSkuName()+"库存不足");
            }else {
                //否则就设置购买数量
                skuDto.setCount(dto.getCount());
                skuDtoList.add(skuDto);
            }
        }
        //定义金额
        BigDecimal total=new BigDecimal(0);
        //定义数量
        int count=0;
        //3.计算金额(完整服务涉及到优惠券，此处只做简单计算处理)
        Iterator<SkuDto> its=skuDtoList.iterator();
        while (its.hasNext()){
            SkuDto skuDto=its.next();
            int num=skuDto.getCount();
            double price=skuDto.getPrice();
            total.add(new BigDecimal(num*price));
            count+=num;
        }
        //4.保存订单（包括订单编号）
        OrderDto orderDto=new OrderDto();
        //先查询最大订单号
        String maxOrderCode=orderMapper.selectMaxOrderCode();
        //根据查询到的最大订单号生成新的订单号
        maxOrderCode= CodeFactory.createOrderCode(maxOrderCode);

        orderDto.setOrderCode(maxOrderCode);
        orderDto.setAllCount(count);
        orderDto.setTotal(total);
        orderDto.setUserId(userId);

        int orderResult=orderMapper.saveOrder(orderDto);
        Assert.isZero(orderResult,"保存订单失败");
        //5.保存订单项
        int orderItemResult=orderItemMapper.saveOrderItem(orderDto.getOrderId(),orderDto.getOrderItemList());
        Assert.isZero(orderItemResult,"保存订单项失败");
        //6.锁定库存
        skuRemoteClient.lockSkuStock(list);

        //抛消息给mq  做一个延迟队列  如果指定时间未支付   取消订单 （将锁定的库存还原）

        //7.清除购物车
        rs=carRemoteClient.cleanCar(userId);
        Assert.isZero(rs.getCode(),"清除购物车失败");
        return maxOrderCode;
    }

}
